/*
 * Copyright (C) 2019 @MTI Ltd.
 *
 */
package com.mti.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

import com.mti.mapper.LfZdryMapper;
import com.mti.service.*;
import com.mti.threadhandle.*;
import com.mti.utils.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mti.component.snowflake.KeyWorker;
import com.mti.configuration.SystemConfig;
import com.mti.constant.ArmingTaskEnum;
import com.mti.dao.kmmodel.KmZdryDto;
import com.mti.dao.model.KmZdryAssistEntity;
import com.mti.dao.model.KmZdryHomeEntity;
import com.mti.dao.model.KmZdryTypeEntity;
import com.mti.dao.model.KmZdryZrbmEntity;
import com.mti.dao.model.LfZdryApproveLogEntity;
import com.mti.dao.model.LfZdryBaseEntity;
import com.mti.dao.model.LfZdryEntity;
import com.mti.dao.model.LfZdryExportDataEntity;
import com.mti.dao.model.LfZdryHistoryEntity;
import com.mti.dao.model.LfZdryHistoryLogEntity;
import com.mti.dao.model.SysDictEntity;
import com.mti.dao.qo.LfZdryQO;
import com.mti.enums.ApproveStatus;
import com.mti.enums.RoleType;
import com.mti.enums.ZdryAssistType;
import com.mti.exception.BusinessException;
import com.mti.jwt.AccountBo;
import com.mti.jwt.RequestUtils;
import com.mti.mapper.LfZdryHistoryMapper;
import com.mti.vo.PredictStatisticsDataItem;
import com.mti.vo.SpecialPersonStatisticsDataVO;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

/**
 * @company 上海道枢信息科技-->
 * @anthor created by zhangmingxin
 * @date 2019/8/15
 * @change
 * @describe describe
 **/
@Slf4j
@Service
@AllArgsConstructor
public class SpecialPersonServiceImpl extends ServiceImpl<LfZdryHistoryMapper, LfZdryHistoryEntity> implements ISpecialPersonService {
    private final ILfZdryService zdryService;
    private final ILfZdryApproveLogService approveLogService;
    private final ISysDictService sysDictService;
    private final ILfZdryZrbmService zdryZrbmService;
    private final LfZdryBaseService lfZdryBaseService;

    @Autowired
    private ISysDictService iSysDictService;
    @Autowired
    private SystemConfig systemConfig;
    @Autowired
	private RequestUtils requestUtils;

    @Autowired
    private KmZdryTypeService kmZdryTypeService;
    @Autowired
    private KmZdryHomeService kmZdryHomeService;
    @Autowired
    private KmZdryAssistService kmZdryAssistService;
    @Autowired
    private CacheableService cacheableService;

    @Autowired
    private KmZdryZrbmService kmZdryZrbmService;
    @Autowired
    private LfZdryExportDataService lfZdryExportDataService;
    @Autowired
    private ExecutorService executorService;
    @Autowired
    private TKmProRightService  tKmProRightService;
    @Autowired
    private LfZdryHistoryLogService lfZdryHistoryLogService;
    @Autowired
    private SpecialPersonComponent specialPersonComponent;
    @Autowired
    private LfZdryMapper lfZdryMapper;
    
    @Autowired
	private GetRemoteIpUtil getRemoteIpUtil;

    @Override
    public Mono<DataBuffer> export(
            String date,
            String exportName,
            LfZdryQO qo,
            ServerWebExchange exchange
    ) throws Exception{
        if (StringUtils.isEmpty(date))
            throw new BusinessException(500, "The argument date cannot be null!");
        // 权限相关代码
        lfZdryBaseService.setUpAuthority(exchange,qo);
        long startTime = System.currentTimeMillis();
        List<LfZdryBaseEntity> data = lfZdryBaseService.findExportExeclData(qo);
//        log.info("导出数据总数：==================>" + data1.size());
        log.info("查询导出数据花费时间=============》"+String.valueOf(System.currentTimeMillis() - startTime));
        long startTime5 = System.currentTimeMillis();
        //去重
//        Set set = new HashSet(data1);
//        List<LfZdryBaseEntity> data = new ArrayList<>(set);
//        log.info("去重耗时=================》" + String.valueOf(System.currentTimeMillis() - startTime5) + "去重前数据总数:" + String.valueOf(data1.size()) + "去重后数据总数:" + String.valueOf(data.size()));

        long startTime1 = System.currentTimeMillis();
		List<LfZdryEntity> list = this.transToLfZdryEntity(data);
		log.info("导出数据组织数据花费时间============》" + String.valueOf(System.currentTimeMillis() - startTime1));
		if(null == list || list.size()==0) throw new BusinessException(500,"未查询到导出数据");

		DefaultDataBuffer dataBuffer = new DefaultDataBufferFactory().allocateBuffer();
        OutputStream outputStream = dataBuffer.asOutputStream();
        // 每次写100行数据，就刷新数据出缓存
        SXSSFWorkbook wb = new SXSSFWorkbook(100);
        CellStyle cellStyleCenter = wb.createCellStyle();
        CellStyle cellStyleLeft = wb.createCellStyle();
        //设置字体颜色
        CellStyle cellStyFont = wb.createCellStyle();
        Font font = wb.createFont();
        font.setColor(IndexedColors.RED.getIndex());
        cellStyFont.setFont(font);
        cellStyFont.setAlignment(HorizontalAlignment.LEFT);
        cellStyFont.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyFont.setBorderBottom(BorderStyle.THIN);
        cellStyFont.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        cellStyFont.setBorderLeft(BorderStyle.THIN);
        cellStyFont.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        cellStyFont.setBorderRight(BorderStyle.THIN);
        cellStyFont.setRightBorderColor(IndexedColors.BLACK.getIndex());
        cellStyFont.setBorderTop(BorderStyle.THIN);
        cellStyFont.setTopBorderColor(IndexedColors.BLACK.getIndex());


        cellStyleCenter.setAlignment(HorizontalAlignment.CENTER); // 居中
        cellStyleCenter.setVerticalAlignment(VerticalAlignment.CENTER); // 居中
        cellStyleLeft.setAlignment(HorizontalAlignment.LEFT);
        cellStyleLeft.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置边框
        cellStyleLeft.setBorderBottom(BorderStyle.THIN);
        cellStyleLeft.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        cellStyleLeft.setBorderLeft(BorderStyle.THIN);
        cellStyleLeft.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        cellStyleLeft.setBorderRight(BorderStyle.THIN);
        cellStyleLeft.setRightBorderColor(IndexedColors.BLACK.getIndex());
        cellStyleLeft.setBorderTop(BorderStyle.THIN);
        cellStyleLeft.setTopBorderColor(IndexedColors.BLACK.getIndex());

//        cellStyleLeft.setFont(font);


        List<List<LfZdryEntity>> exportData = ListUtils.splitList(list,5000);

        ExecutorService pool = Executors.newFixedThreadPool(exportData.size());

        CountDownLatch downLatch = new CountDownLatch(exportData.size());
        long startTime4 = System.currentTimeMillis();
        for(int i=0;i<exportData.size();i++){
            StringBuilder sb = null;
            if(null == exportName||exportName.length()<=0) sb = new StringBuilder("重点人员");
            else sb = new StringBuilder(exportName);
            sb.append("-").append(i);
            SXSSFSheet sh = wb.createSheet(sb.toString());
            sh.trackAllColumnsForAutoSizing();
            pool.execute(new ZdryExportHandle(sh,cellStyleCenter,cellStyleLeft,exportData.get(i),date,exportName,iSysDictService,downLatch,cellStyFont));
        }
        downLatch.await();
        log.info("导出时写出数据花费时间========444==========》" + String.valueOf(System.currentTimeMillis() - startTime4));
        try {
            long startTime3 = System.currentTimeMillis();
            wb.write(outputStream);
            log.info("导出时写出数据花费时间==================》" + String.valueOf(System.currentTimeMillis() - startTime3));
        } catch (IOException e) {
            log.error("error == >{}", e.getMessage());
        } finally {
            try {
                wb.close();
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                log.error("error == >{}", e.getMessage());
            }
            pool.shutdown();
        }
        return Mono.just(dataBuffer);
    }

    @Override
    public Mono<DataBuffer> export1(
            List<String> listNumber,
            String date,
            String exportName,
            ServerWebExchange exchange
    ) throws Exception{
        if (StringUtils.isEmpty(date))
            throw new BusinessException(500, "The argument date cannot be null!");
        // 权限相关代码
        lfZdryBaseService.setUpAuthority(exchange,new LfZdryQO());
        List<LfZdryBaseEntity> data = lfZdryBaseService.findExportExeclDataNumber(listNumber);
        List<LfZdryEntity> list = this.transToLfZdryEntity(data);
        if(null == list || list.size()==0) throw new BusinessException(500,"未查询到导出数据");

        DefaultDataBuffer dataBuffer = new DefaultDataBufferFactory().allocateBuffer();
        OutputStream outputStream = dataBuffer.asOutputStream();
        // 每次写100行数据，就刷新数据出缓存
        SXSSFWorkbook wb = new SXSSFWorkbook(100);
        CellStyle cellStyleCenter = wb.createCellStyle();
        CellStyle cellStyleLeft = wb.createCellStyle();
        //设置字体颜色
        CellStyle cellStyFont = wb.createCellStyle();
        Font font = wb.createFont();
        font.setColor(IndexedColors.RED.getIndex());
        cellStyFont.setFont(font);
        cellStyFont.setAlignment(HorizontalAlignment.LEFT);
        cellStyFont.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyFont.setBorderBottom(BorderStyle.THIN);
        cellStyFont.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        cellStyFont.setBorderLeft(BorderStyle.THIN);
        cellStyFont.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        cellStyFont.setBorderRight(BorderStyle.THIN);
        cellStyFont.setRightBorderColor(IndexedColors.BLACK.getIndex());
        cellStyFont.setBorderTop(BorderStyle.THIN);
        cellStyFont.setTopBorderColor(IndexedColors.BLACK.getIndex());


        cellStyleCenter.setAlignment(HorizontalAlignment.CENTER); // 居中
        cellStyleCenter.setVerticalAlignment(VerticalAlignment.CENTER); // 居中
        cellStyleLeft.setAlignment(HorizontalAlignment.LEFT);
        cellStyleLeft.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置边框
        cellStyleLeft.setBorderBottom(BorderStyle.THIN);
        cellStyleLeft.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        cellStyleLeft.setBorderLeft(BorderStyle.THIN);
        cellStyleLeft.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        cellStyleLeft.setBorderRight(BorderStyle.THIN);
        cellStyleLeft.setRightBorderColor(IndexedColors.BLACK.getIndex());
        cellStyleLeft.setBorderTop(BorderStyle.THIN);
        cellStyleLeft.setTopBorderColor(IndexedColors.BLACK.getIndex());

//        cellStyleLeft.setFont(font);


        List<List<LfZdryEntity>> exportData = ListUtils.splitList(list,15000);

        ExecutorService pool = Executors.newFixedThreadPool(exportData.size());

        CountDownLatch downLatch = new CountDownLatch(exportData.size());
        for(int i=0;i<exportData.size();i++){
            StringBuilder sb = null;
            if(null == exportName||exportName.length()<=0) sb = new StringBuilder("重点人员");
            else sb = new StringBuilder(exportName);
            sb.append("-").append(i);
            SXSSFSheet sh = wb.createSheet(sb.toString());
            sh.trackAllColumnsForAutoSizing();
            pool.execute(new ZdryExportHandle(sh,cellStyleCenter,cellStyleLeft,exportData.get(i),date,exportName,iSysDictService,downLatch,cellStyFont));
        }
        downLatch.await();
        try {
            wb.write(outputStream);
        } catch (IOException e) {
            log.error("error == >{}", e.getMessage());
        } finally {
            try {
                wb.close();
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                log.error("error == >{}", e.getMessage());
            }
            pool.shutdown();
        }
        return Mono.just(dataBuffer);
    }

    /**
     * 导出重点人员时 整理数据
     * @param data
     * @return
     */
    private List<LfZdryEntity> transToLfZdryEntity(List<LfZdryBaseEntity> data) {
        if(null == data || data.size()<=0) return null;
        List<LfZdryEntity> result = new ArrayList<>();
        for(LfZdryBaseEntity zdry : data){
            LfZdryEntity z = new LfZdryEntity();
            z.setXm(zdry.getXm());
            z.setSfzh(zdry.getSfzh());
            StringBuilder dhhm = new StringBuilder();
            StringBuilder wx = new StringBuilder();
            StringBuilder qq = new StringBuilder();
            StringBuilder mxcph = new StringBuilder();
            StringBuilder sjcph = new StringBuilder();
            if(null != zdry.getAssistList()&& zdry.getAssistList().size()>0){
             Map<Integer,List<KmZdryAssistEntity>>  assists = zdry.getAssistList().stream().collect(Collectors.groupingBy(KmZdryAssistEntity::getInfoType));
                List<KmZdryAssistEntity> dh = assists.get(ZdryAssistType.TEL.getType());
                if(null != dh && dh.size()>0){
                    dh.forEach(e->{
                        if(dhhm.length()>0) dhhm.append("/").append(e.getInfoValue());
                        else dhhm.append(e.getInfoValue());
                    });
                }
                List<KmZdryAssistEntity> w = assists.get(ZdryAssistType.WX.getType());
                if(null != w && w.size()>0){
                    w.forEach(e->{
                        if(wx.length()>0) wx.append("/").append(e.getInfoValue());
                        else wx.append(e.getInfoValue());
                    });
                }
                List<KmZdryAssistEntity> q = assists.get(ZdryAssistType.QQ.getType());
                if(null != q && q.size()>0){
                    q.forEach(e->{
                        if(qq.length()>0) qq.append("/").append(e.getInfoValue());
                        else qq.append(e.getInfoValue());
                    });
                }
                List<KmZdryAssistEntity> mx = assists.get(ZdryAssistType.MXCPH.getType());
                if(null != mx && mx.size()>0){
                    mx.forEach(e->{
                        if(mxcph.length()>0) mxcph.append("/").append(e.getInfoValue());
                        else mxcph.append(e.getInfoValue());
                    });
                }
                List<KmZdryAssistEntity> sj = assists.get(ZdryAssistType.SJCPH.getType());
                if(null != sj && sj.size()>0){
                    sj.forEach(e->{
                        if(sjcph.length()>0) sjcph.append("/").append(e.getInfoValue());
                        else sjcph.append(e.getInfoValue());
                    });
                }
            }
            z.setSjh(dhhm.toString());
            z.setWx(wx.toString());
            z.setQq(qq.toString());
            z.setMxcph(mxcph.toString());
            z.setSjsyclhp(sjcph.toString());
            z.setSszsmc(zdry.getSszsmc());
            z.setSsxq(zdry.getSsxq());
            z.setSspcs(zdry.getSspcs());
            z.setOid(zdry.getSspcsId());
            z.setGkmj(zdry.getGkmj());
            z.setMjlxdh(zdry.getMjlxdh());
            z.setHjs(zdry.getHjs());
            z.setHjsS(zdry.getHjss());
            z.setHjx(zdry.getHjx());
            z.setHjdX(zdry.getHjdX());
            z.setHjd(zdry.getHjd());
            //处理居住地
            List<KmZdryHomeEntity> homes = zdry.getJzdList();
            StringBuilder xzzs = new StringBuilder();
            StringBuilder xzzss = new StringBuilder();
            StringBuilder xzzx = new StringBuilder();
            StringBuilder xzz = new StringBuilder();
            if(null != homes && homes.size()>0){
                homes.forEach(e->{
                    if(xzzs.length()>0) xzzs.append("/").append(e.getXzzs());
                    else xzzs.append(e.getXzzs());
                    if(xzzss.length()>0) xzzss.append("/").append(e.getXzzss());
                    else xzzss.append(e.getXzzss());
                    if(xzzx.length()>0) xzzx.append("/").append(e.getXzzx());
                    else xzzx.append(e.getXzzx());
                    if(xzz.length()>0) xzz.append("/").append(e.getXzz());
                    else xzz.append(e.getXzz());
                });
            }
            z.setXzzs(xzzs.toString());
            z.setXzzsS(xzzss.toString());
            z.setXzzx(xzzx.toString());
            z.setXzz(xzz.toString());
            // 人员大类 人员小类
            List<KmZdryTypeEntity> zt = zdry.getTypeList();
            StringBuilder dl = new StringBuilder();
            StringBuilder xl = new StringBuilder();
            if(null != zt && zt.size()>0){
                zt.forEach(e->{
                    if(dl.length()>0) dl.append("/").append(e.getRylb());
                    else dl.append(e.getRylb());
                    if(xl.length()>0) xl.append("/").append(e.getXl());
                    else xl.append(e.getXl());
                });
            }
            z.setRylbx(dl.toString());
            z.setXl(xl.toString());
            z.setRysx(zdry.getRysx());
            z.setGkjbx(zdry.getGkjb());
            z.setWkzt(zdry.getWkzt());
            z.setYjczlb(zdry.getYjczlb());
            z.setBz(zdry.getBz());
            z.setAppeal(zdry.getAppeal());
            result.add(z);
        }
        return result;
    }

    @Override
    public IPage<LfZdryHistoryEntity> pageData(Integer page, Integer size, String date, String rangeVal, String rangeType, String zrbm) {
        QueryWrapper<LfZdryHistoryEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(LfZdryHistoryEntity::getRecordVersion, date);
        if (!StringUtils.isEmpty(rangeVal)) {//范围值不为空
            List<String> vs = Arrays.asList(rangeVal.split(","));
            switch (rangeType) {
                case "1": {
                    queryWrapper.lambda().in(LfZdryHistoryEntity::getOwnRangeId, vs);
                }
                break;
                case "2": {
                    if (!vs.isEmpty())
                        queryWrapper.lambda().in(LfZdryHistoryEntity::getPoliceHomeId, vs);
                }
                break;
            }
        }
        if (!StringUtils.isEmpty(zrbm))
            queryWrapper.lambda().eq(LfZdryHistoryEntity::getZrbm, zrbm);
        IPage<LfZdryHistoryEntity> iPage = this.page(new Page<>(page, size), queryWrapper);
        iPage.getRecords().parallelStream().forEach(item -> {
            String ciper = zdryService.getCiperBySfzh(item.getIdentityId());
            item.setOwnCarType(StringUtils.isEmpty(ciper) ? "暂无" : ciper);
        });
        return iPage;
    }

    @Override
    public IPage<LfZdryHistoryEntity> pageDataV2(Integer page, Integer size, String date, String rangeVal, String rangeType, String zrbm) {
        QueryWrapper<LfZdryHistoryEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(LfZdryHistoryEntity::getRecordVersion, date);
        switch (rangeType) {
            case "1": // 市局根据责任部门过滤数据
                // 市局指挥中心角色，zrbm为空，查询所有数据
                // 市局特殊警种，zrbm必填，根据zrbm过滤数据
                if (!StringUtils.isEmpty(zrbm)) {
                    queryWrapper.lambda().eq(LfZdryHistoryEntity::getZrbm, zrbm);
                }
                break;
            case "2":// 分局根据责任部门和own_range_id过滤数据
                // 分局指挥中心角色，rangeVal必填，zrbm为空，根据rangeVal查询当前分局及下属派出所所有数据
                // 分局特殊警种，rangeVal必填，zrbm必填，根据zrbm和rangeVal过滤当前分局及下属派出所所有数据
                if (!StringUtils.isEmpty(zrbm)) {
                    queryWrapper.lambda().eq(LfZdryHistoryEntity::getZrbm, zrbm);
                }
                if (!rangeVal.isEmpty()) {
                    queryWrapper.like("own_range_id", rangeVal.substring(0, 6));
                }
                break;
            case "3": // 派出所根据police_home_id过滤数据
                if (!rangeVal.isEmpty()) {
                    queryWrapper.lambda().in(LfZdryHistoryEntity::getPoliceHomeId, rangeVal);
                }
                break;
            default:
                log.error("rangeType " + rangeType + "is unknown");
                return null;
        }
        IPage<LfZdryHistoryEntity> iPage = this.page(new Page<>(page, size), queryWrapper);
        iPage.getRecords().parallelStream().forEach(item -> {
            String ciper = zdryService.getCiperBySfzh(item.getIdentityId());
            item.setOwnCarType(StringUtils.isEmpty(ciper) ? "暂无" : ciper);
        });
        return iPage;
    }

    // 在控 失控 未上报统计
    public int getIsControlCountByVersionV2(String date, String zrbm, String rangeVal, String rangeType, String isControl) {

        QueryWrapper<LfZdryHistoryEntity> queryWrapper = new QueryWrapper<LfZdryHistoryEntity>();
        queryWrapper.eq("record_version", date);

        if (isControl.equals("0")) {
            queryWrapper.eq("is_control", "失控");
        } else if (isControl.equals("1")) {
            queryWrapper.eq("is_control", "在控");
        } else if (isControl.equals("2")) {
            queryWrapper.eq("is_control", "未上报");
        }

        switch (rangeType) {
            case "1":
                if (!StringUtils.isEmpty(zrbm)) {
                    queryWrapper.lambda().eq(LfZdryHistoryEntity::getZrbm, zrbm);
                }
                break;
            case "2":
                if (!rangeVal.isEmpty()) {
                    queryWrapper.like("own_range_id", rangeVal.substring(0, 6));
                }
                if (!StringUtils.isEmpty(zrbm)) {
                    queryWrapper.lambda().eq(LfZdryHistoryEntity::getZrbm, zrbm);
                }
                break;
            case "3":
                if (!rangeVal.isEmpty()) {
                    queryWrapper.lambda().in(LfZdryHistoryEntity::getPoliceHomeId, rangeVal);
                }
                break;
            default:
                log.error("rangeType " + rangeType + " is unkown");
                return 0;
        }

        List<LfZdryHistoryEntity> lfZdryHistoryEntityList = this.list(queryWrapper);
        return lfZdryHistoryEntityList.size();
    }


    // 在控 失控 未上报统计
    public int getIsControlCountByVersion(String date, String rangeVal, String rangeType, String isControl) {

        QueryWrapper<LfZdryHistoryEntity> queryWrapper = new QueryWrapper<LfZdryHistoryEntity>();
        queryWrapper.eq("record_version", date);

        if (isControl.equals("0")) {
            queryWrapper.eq("is_control", "失控");
        } else if (isControl.equals("1")) {
            queryWrapper.eq("is_control", "在控");
        } else if (isControl.equals("2")) {
            queryWrapper.eq("is_control", "未上报");
        }

        if (!StringUtils.isEmpty(rangeVal)) {//范围值不为空
            List<String> vs = Arrays.asList(rangeVal.split(","));
            switch (rangeType) {
                case "1": {
                    queryWrapper.lambda().in(LfZdryHistoryEntity::getOwnRangeId, vs);
                }
                break;
                case "2": {
                    if (!vs.isEmpty())
                        queryWrapper.lambda().in(LfZdryHistoryEntity::getPoliceHomeId, vs);
                }
                break;
            }
        }

        List<LfZdryHistoryEntity> lfZdryHistoryEntityList = this.list(queryWrapper);
        return lfZdryHistoryEntityList.size();
    }


    @Override
    public List<SpecialPersonStatisticsDataVO> getSpecialPersonStatisticsData(LfZdryQO qo) {
        List<SpecialPersonStatisticsDataVO> data = null;
//        if(qo.getYjczlbList() != null && qo.getYjczlbList().size() > 0 || qo.getWkztList() != null && qo.getWkztList().size() > 0 || qo.getRysxList() != null && qo.getRysxList().size() > 0 || qo.getRylbxList() != null && qo.getRysxList().size() > 0 || qo.getGkjbxList() != null && qo.getGkjbxList().size() > 0 || qo.getYnzsList() != null && qo.getYnzsList().size() > 0 || qo.getZrbmList() != null && qo.getZrbmList().size() > 0){
        if(qo.getYjczlbList() != null || qo.getWkztList() != null  || qo.getRysxList() != null || qo.getRylbxList() != null || qo.getGkjbxList() != null  || qo.getYnzsList() != null || qo.getZrbmList() != null){
            if(null != qo.getRoleType() && qo.getRoleType().length()>0){
                    List<String> zrbmList = qo.getZrbmList();
                    if(zrbmList != null){
                        zrbmList.addAll(Arrays.asList(qo.getRoleType().split(",")));
                        qo.setZrbmList(zrbmList);
                        data = lfZdryBaseService.getSpecialPersonStatisticsForPoliceCategory(qo);
                    }else {
                        List<String> zrbmList1 = new ArrayList<>();
                        zrbmList1.addAll(Arrays.asList(qo.getRoleType().split(",")));
                        qo.setZrbmList(zrbmList1);
                        data = lfZdryBaseService.getSpecialPersonStatisticsForPoliceCategory(qo);
                    }
            }else {
                data = lfZdryBaseService.getSpecialPersonStatisticsForPoliceCategory(qo);
            }
        } else{
            if(null != qo.getRoleType() && qo.getRoleType().length()>0){
                List<String> zrbmList = new ArrayList<>();
                zrbmList.addAll(Arrays.asList(qo.getRoleType().split(",")));
                qo.setZrbmList(zrbmList);
                data = lfZdryBaseService.getSpecialPersonStatisticsForPoliceCategory(qo);
            }else {
                data = lfZdryBaseService.getSpecialPersonStatistics(qo);
            }
        }
        //List<SpecialPersonStatisticsDataVO> data = lfZdryBaseService.getSpecialPersonStatistics(rangeType, rangeVal, zrdw);
        if (!data.isEmpty()) {
            List<SpecialPersonStatisticsDataVO> list = new ArrayList<>();
            Map<String, List<SpecialPersonStatisticsDataVO>> groupData = data
                    .parallelStream()
                    .filter(item -> !StringUtils.isEmpty(item.getOrgName()) && !StringUtils.isEmpty(item.getOname()))
                    .collect(Collectors.groupingBy(SpecialPersonStatisticsDataVO::getOrgName));
            //遍历所有分局
            for (Map.Entry<String, List<SpecialPersonStatisticsDataVO>> m : groupData.entrySet()) {
                SpecialPersonStatisticsDataVO vo = new SpecialPersonStatisticsDataVO();
                vo.setParent(true);
                //vo.setOrgId(m.getKey());
                if (m.getValue().isEmpty())
                    continue;
                vo.setOrgName(m.getValue().get(0).getOrgName());
                vo.setOrgId(m.getValue().get(0).getOrgId());

                List<SpecialPersonStatisticsDataVO> child = new ArrayList<>();
                Map<String, List<SpecialPersonStatisticsDataVO>> innerItem = m.getValue().parallelStream().collect(Collectors.groupingBy(SpecialPersonStatisticsDataVO::getOname));
                //遍历所有派出所
                for (Map.Entry<String, List<SpecialPersonStatisticsDataVO>> innerM : innerItem.entrySet()) {
                    innerM.getValue().get(0).setParent(false);
                    vo.setTotalCount(vo.getTotalCount() + innerM.getValue().get(0).getTotalCount());
                    vo.setControlCount(vo.getControlCount() + innerM.getValue().get(0).getControlCount());
                    vo.setLoseCount(vo.getLoseCount() + innerM.getValue().get(0).getLoseCount());
                    vo.setUnReportCount(vo.getUnReportCount() + innerM.getValue().get(0).getUnReportCount());

                    vo.setPoliticalCount(vo.getPoliticalCount() + innerM.getValue().get(0).getPoliticalCount());
                    vo.setHongKongCount(vo.getHongKongCount() + innerM.getValue().get(0).getHongKongCount());
                    vo.setTibetCount(vo.getTibetCount() + innerM.getValue().get(0).getTibetCount());
                    vo.setCultsCount(vo.getCultsCount() + innerM.getValue().get(0).getCultsCount());
                    vo.setTerroristCount(vo.getTerroristCount() + innerM.getValue().get(0).getTerroristCount());
                    vo.setStableCount(vo.getStableCount() + innerM.getValue().get(0).getStableCount());
                    vo.setPersonsCount(vo.getPersonsCount() + innerM.getValue().get(0).getPersonsCount());
                    vo.setReportCount(vo.getReportCount() + innerM.getValue().get(0).getReportCount());
                    vo.setNetCount(vo.getNetCount() + innerM.getValue().get(0).getNetCount());
                    vo.setCarCount(vo.getCarCount() + innerM.getValue().get(0).getCarCount());
                    vo.setDrugCount(vo.getDrugCount() + innerM.getValue().get(0).getDrugCount());
                    vo.setInnormalCount(vo.getInnormalCount() + innerM.getValue().get(0).getInnormalCount());
                    vo.setExtremeCount(vo.getExtremeCount() + innerM.getValue().get(0).getExtremeCount());
                    vo.setCriminalRecordCount(vo.getCriminalRecordCount() + innerM.getValue().get(0).getCriminalRecordCount());
                    vo.setOtherCount(vo.getOtherCount() + innerM.getValue().get(0).getOtherCount());

                    vo.setPoliticalControlCount(vo.getPoliticalControlCount() + innerM.getValue().get(0).getPoliticalControlCount());
                    vo.setHongKongControlCount(vo.getHongKongControlCount() + innerM.getValue().get(0).getHongKongControlCount());
                    vo.setTibetControlCount(vo.getTibetControlCount() + innerM.getValue().get(0).getTibetControlCount());
                    vo.setCultsControlCount(vo.getCultsControlCount() + innerM.getValue().get(0).getCultsControlCount());
                    vo.setTerroristControlCount(vo.getTerroristControlCount() + innerM.getValue().get(0).getTerroristControlCount());
                    vo.setStableControlCount(vo.getStableControlCount() + innerM.getValue().get(0).getStableControlCount());
                    vo.setPersonsControlCount(vo.getPersonsControlCount() + innerM.getValue().get(0).getPersonsControlCount());
                    vo.setReportControlCount(vo.getReportControlCount() + innerM.getValue().get(0).getReportControlCount());
                    vo.setNetControlCount(vo.getNetControlCount() + innerM.getValue().get(0).getNetControlCount());
                    vo.setCarControlCount(vo.getCarControlCount() + innerM.getValue().get(0).getCarControlCount());
                    vo.setDrugControlCount(vo.getDrugControlCount() + innerM.getValue().get(0).getDrugControlCount());
                    vo.setInnormalControlCount(vo.getInnormalControlCount() + innerM.getValue().get(0).getInnormalControlCount());
                    vo.setExtremeControlCount(vo.getExtremeControlCount() + innerM.getValue().get(0).getExtremeControlCount());
                    vo.setCriminalRecordControlCount(vo.getCriminalRecordControlCount() + innerM.getValue().get(0).getCriminalRecordControlCount());
                    vo.setOtherControlCount(vo.getOtherControlCount() + innerM.getValue().get(0).getOtherControlCount());


                    vo.setHighLevelCount(vo.getHighLevelCount() + innerM.getValue().get(0).getHighLevelCount());
                    vo.setMiddleLevelCount(vo.getMiddleLevelCount() + innerM.getValue().get(0).getMiddleLevelCount());
                    vo.setLowLevelCount(vo.getLowLevelCount() + innerM.getValue().get(0).getLowLevelCount());
                    vo.setGrayLevelCount(vo.getGrayLevelCount() + innerM.getValue().get(0).getGrayLevelCount());
                    vo.setDeadLevelCount(vo.getDeadLevelCount() + innerM.getValue().get(0).getDeadLevelCount());

                    vo.setHighLevelControlCount(vo.getHighLevelControlCount() + innerM.getValue().get(0).getHighLevelControlCount());
                    vo.setMiddleLevelControlCount(vo.getMiddleLevelControlCount() + innerM.getValue().get(0).getMiddleLevelControlCount());
                    vo.setLowLevelControlCount(vo.getLowLevelControlCount() + innerM.getValue().get(0).getLowLevelControlCount());
                    vo.setGrayLevelControlCount(vo.getGrayLevelControlCount() + innerM.getValue().get(0).getGrayLevelControlCount());
                    vo.setDeadLevelControlCount(vo.getDeadLevelControlCount() + innerM.getValue().get(0).getDeadLevelControlCount());

                    child.add(innerM.getValue().get(0));
                }
                vo.setChildList(child);
                list.add(vo);
            }
            long count = list.parallelStream().map(SpecialPersonStatisticsDataVO::getTotalCount).reduce(Long::sum).orElse(0L);
            log.info("重点人员总数 ==>{}", count);
            return list;
        }
        return null;
    }

    @Override
    public List<PredictStatisticsDataItem> getPredictSpecialPersonStatisticsData(String rangeType, String rangeVal, String start, String end) {
        //按人统计
        List<PredictStatisticsDataItem> predictStatisticsDataItems = zdryService.getPredictSpecialPersonStatistics(rangeType, rangeVal, StringUtils.isEmpty(start) ? start : start.replace("-", "").replace(" ", ""), StringUtils.isEmpty(end) ? end : end.replace("-", "").replace(" ", ""));
        if (predictStatisticsDataItems == null || predictStatisticsDataItems.isEmpty())
            return null;
        //按人次统计
        List<PredictStatisticsDataItem> dropStatisticsDataItems = zdryService.getPredictEventSpecialPersonStatistics(rangeType, rangeVal, StringUtils.isEmpty(start) ? start : start.replace("-", "").replace(" ", ""), StringUtils.isEmpty(end) ? end : end.replace("-", "").replace(" ", ""));
        //根据所属辖区分组
        Map<String, List<PredictStatisticsDataItem>> groupPredictDataItemMap = predictStatisticsDataItems.parallelStream().collect(Collectors.groupingBy(PredictStatisticsDataItem::getSsxqId));
        Map<String, List<PredictStatisticsDataItem>> groupEventDateItemMap = dropStatisticsDataItems.parallelStream().collect(Collectors.groupingBy(PredictStatisticsDataItem::getSsxqId));
        //遍历所属辖区，统计每个辖区所有数据
        List<PredictStatisticsDataItem> rootDataList = new ArrayList<>();
        for (Map.Entry<String, List<PredictStatisticsDataItem>> e : groupPredictDataItemMap.entrySet()) {
            String k = e.getKey();
            List<PredictStatisticsDataItem> v = e.getValue();
            PredictStatisticsDataItem predictStatisticsDataItem = new PredictStatisticsDataItem();
            predictStatisticsDataItem.setIsParent(true);
            predictStatisticsDataItem.setSsxq(v.get(0).getSsxq());
            predictStatisticsDataItem.setSsxqId(v.get(0).getSsxqId());
            //按照派出所分组
            Map<String, List<PredictStatisticsDataItem>> innerGroup = v.parallelStream().collect(Collectors.groupingBy(PredictStatisticsDataItem::getOid));
            Map<String, List<PredictStatisticsDataItem>> innerEventGroup = groupEventDateItemMap.containsKey(k) ? groupEventDateItemMap.get(k).parallelStream().collect(Collectors.groupingBy(PredictStatisticsDataItem::getOid)) : null;
            //设置子级数据
            predictStatisticsDataItem.setChildList(v);
            //遍历派出所数据
            for (Map.Entry<String, List<PredictStatisticsDataItem>> entry : innerGroup.entrySet()) {
                //累加父级数据
                List<PredictStatisticsDataItem> iv = entry.getValue();
                predictStatisticsDataItem.setUnDropCount(predictStatisticsDataItem.getUnDropCount() + iv.parallelStream().map(PredictStatisticsDataItem::getUnDropCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setDropCount(predictStatisticsDataItem.getDropCount() + iv.parallelStream().map(PredictStatisticsDataItem::getDropCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setTotal(predictStatisticsDataItem.getTotal() + iv.parallelStream().map(PredictStatisticsDataItem::getTotal).reduce(Long::sum).get());
                predictStatisticsDataItem.setIsControlCount(predictStatisticsDataItem.getIsControlCount() + iv.parallelStream().map(PredictStatisticsDataItem::getIsControlCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setLoseControlCount(predictStatisticsDataItem.getLoseControlCount() + iv.parallelStream().map(PredictStatisticsDataItem::getLoseControlCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setOneLevelIsControlCount(predictStatisticsDataItem.getOneLevelIsControlCount() + iv.parallelStream().map(PredictStatisticsDataItem::getOneLevelIsControlCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setOneLevelLoseControlCount(predictStatisticsDataItem.getOneLevelLoseControlCount() + iv.parallelStream().map(PredictStatisticsDataItem::getOneLevelLoseControlCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setTwoLevelIsControlCount(predictStatisticsDataItem.getTwoLevelIsControlCount() + iv.parallelStream().map(PredictStatisticsDataItem::getTwoLevelIsControlCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setTwoLevelLoseControlCount(predictStatisticsDataItem.getTwoLevelLoseControlCount() + iv.parallelStream().map(PredictStatisticsDataItem::getTwoLevelLoseControlCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setThreeLevelIsControlCount(predictStatisticsDataItem.getThreeLevelIsControlCount() + iv.parallelStream().map(PredictStatisticsDataItem::getThreeLevelIsControlCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setThreeLevelLoseControlCount(predictStatisticsDataItem.getThreeLevelLoseControlCount() + iv.parallelStream().map(PredictStatisticsDataItem::getThreeLevelLoseControlCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setIllegalReportCount(predictStatisticsDataItem.getIllegalReportCount() + iv.parallelStream().map(PredictStatisticsDataItem::getIllegalReportCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setArmyCount(predictStatisticsDataItem.getArmyCount() + iv.parallelStream().map(PredictStatisticsDataItem::getArmyCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setOtherCount(predictStatisticsDataItem.getOtherCount() + iv.parallelStream().map(PredictStatisticsDataItem::getOtherCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setOtherEventCount(predictStatisticsDataItem.getOtherEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getOtherEventCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setPoliticalCount(predictStatisticsDataItem.getPoliticalCount() + iv.parallelStream().map(PredictStatisticsDataItem::getPoliticalCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setInsanityCount(predictStatisticsDataItem.getInsanityCount() + iv.parallelStream().map(PredictStatisticsDataItem::getInsanityCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setCriminalInvestCount(predictStatisticsDataItem.getCriminalInvestCount() + iv.parallelStream().map(PredictStatisticsDataItem::getCriminalInvestCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setPoliceCount(predictStatisticsDataItem.getPoliceCount() + iv.parallelStream().map(PredictStatisticsDataItem::getPoliceCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setCriminalReleaseCount(predictStatisticsDataItem.getCriminalReleaseCount() + iv.parallelStream().map(PredictStatisticsDataItem::getCriminalReleaseCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setDealInvestCount(predictStatisticsDataItem.getDealInvestCount() + iv.parallelStream().map(PredictStatisticsDataItem::getDealInvestCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setIllegalEventReportCount(predictStatisticsDataItem.getIllegalEventReportCount() + iv.parallelStream().map(PredictStatisticsDataItem::getIllegalEventReportCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setArmyEventCount(predictStatisticsDataItem.getArmyEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getArmyEventCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setPoliticalEventCount(predictStatisticsDataItem.getPoliticalEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getPoliticalEventCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setInsanityEventCount(predictStatisticsDataItem.getInsanityEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getInsanityEventCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setCriminalInvestEventCount(predictStatisticsDataItem.getCriminalInvestEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getCriminalInvestEventCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setPoliceEventCount(predictStatisticsDataItem.getPoliceEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getPoliceEventCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setCriminalReleaseEventCount(predictStatisticsDataItem.getCriminalReleaseEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getCriminalReleaseEventCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setDealInvestEventCount(predictStatisticsDataItem.getDealInvestEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getDealInvestEventCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setTerroristCount(predictStatisticsDataItem.getTerroristCount() + iv.parallelStream().map(PredictStatisticsDataItem::getTerroristCount).reduce(Long::sum).get());
                predictStatisticsDataItem.setTerroristEventCount(predictStatisticsDataItem.getTerroristEventCount() + iv.parallelStream().map(PredictStatisticsDataItem::getTerroristEventCount).reduce(Long::sum).get());

                if (innerEventGroup != null) {
                    List<PredictStatisticsDataItem> ive = innerEventGroup.getOrDefault(entry.getKey(), null);
                    if (ive != null && !ive.isEmpty()) {
                        predictStatisticsDataItem.setJzDropCount(predictStatisticsDataItem.getJzDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getJzDropCount).reduce(Long::sum).get());
                        predictStatisticsDataItem.setFaceDropCount(predictStatisticsDataItem.getFaceDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getFaceDropCount).reduce(Long::sum).get());
                        predictStatisticsDataItem.setBarrierDropCount(predictStatisticsDataItem.getBarrierDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getBarrierDropCount).reduce(Long::sum).get());
                        predictStatisticsDataItem.setTicketDropCount(predictStatisticsDataItem.getTicketDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getTicketDropCount).reduce(Long::sum).get());
                        predictStatisticsDataItem.setMobileDropCount(predictStatisticsDataItem.getMobileDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getMobileDropCount).reduce(Long::sum).get());
                        predictStatisticsDataItem.setHotelDropCount(predictStatisticsDataItem.getHotelDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getHotelDropCount).reduce(Long::sum).get());
                        predictStatisticsDataItem.setCardDropCount(predictStatisticsDataItem.getCardDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getCardDropCount).reduce(Long::sum).get());
                        predictStatisticsDataItem.setPeaceDropCount(predictStatisticsDataItem.getPeaceDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getPeaceDropCount).reduce(Long::sum).get());
                        predictStatisticsDataItem.setCheckDropCount(predictStatisticsDataItem.getCheckDropCount() + ive.parallelStream().map(PredictStatisticsDataItem::getCheckDropCount).reduce(Long::sum).get());
//                        predictStatisticsDataItem.setBusDropCount(predictStatisticsDataItem.getBusDropCount()+ive.parallelStream().map(PredictStatisticsDataItem::getBusDropCount).reduce(Long::sum).get());
//                        predictStatisticsDataItem.setUncontrolDropCount(predictStatisticsDataItem.getUncontrolDropCount()+ive.parallelStream().map(PredictStatisticsDataItem::getUncontrolDropCount).reduce(Long::sum).get());
                        //设置派出所数据
                        if (!iv.isEmpty()) {
                            iv.get(0).setFaceDropCount(ive.get(0).getFaceDropCount());
                            iv.get(0).setCardDropCount(ive.get(0).getCardDropCount());
//                            iv.get(0).setBusDropCount(ive.get(0).getBusDropCount());
//                            iv.get(0).setUncontrolDropCount(ive.get(0).getUncontrolDropCount());
                            iv.get(0).setPeaceDropCount(ive.get(0).getPeaceDropCount());
                            iv.get(0).setJzDropCount(ive.get(0).getJzDropCount());
                            iv.get(0).setCheckDropCount(ive.get(0).getCheckDropCount());
                            iv.get(0).setTicketDropCount(ive.get(0).getTicketDropCount());
                            iv.get(0).setBarrierDropCount(ive.get(0).getBarrierDropCount());
                            iv.get(0).setMobileDropCount(ive.get(0).getMobileDropCount());
                            iv.get(0).setHotelDropCount(ive.get(0).getHotelDropCount());
                        }
                    }
                }
            }
            rootDataList.add(predictStatisticsDataItem);
        }
        log.info("personCount===>{}", rootDataList.parallelStream().map(PredictStatisticsDataItem::getTotal).reduce(Long::sum).orElse(0L));
        return rootDataList;
    }

    @Override
    public void updatePersonStatus(String personId) {
        this.update(new UpdateWrapper<LfZdryHistoryEntity>().lambda().eq(LfZdryHistoryEntity::getIdentityId, personId).eq(LfZdryHistoryEntity::getRecordVersion, LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))).set(LfZdryHistoryEntity::getIsControl, "在控"));
    }

    @Override
    @Transactional
    public void approveSpecialPerson(LfZdryApproveLogEntity logEntity) {
        if (StringUtils.isEmpty(logEntity.getSpId()))
            throw new BusinessException(500, "重点人员ID不能为空");
        if (StringUtils.isEmpty(logEntity.getOperateDept()) || StringUtils.isEmpty(logEntity.getCreator()))
            throw new BusinessException(500, "操作人或部门不能为空");
        if (StringUtils.isEmpty(logEntity.getApproveStatus()))
            throw new BusinessException(500, "操作状态不能为空");
        else {
            int aStatus = Integer.parseInt(logEntity.getApproveStatus());
            if (aStatus < ArmingTaskEnum.WAIT_POLICE_TYPE.ordinal() || aStatus > ArmingTaskEnum.FINISH_TYPE.ordinal())
                throw new BusinessException(500, "非法操作状态");
            //查询重点人员信息
            List<String> personIds = Arrays.asList(logEntity.getSpId().split(","));
            //更新重点人员状态
            zdryService.update(
                    new UpdateWrapper<LfZdryEntity>()
                            .lambda()

                            .lt(LfZdryEntity::getApproveStatus, String.valueOf(ArmingTaskEnum.FINISH_TYPE.ordinal()))
                            .in(LfZdryEntity::getId, personIds)

                            .set(LfZdryEntity::getApproveStatus, logEntity.getApproveStatus())
            );
            //插入日志
            CopyOnWriteArrayList<LfZdryApproveLogEntity> logEntityList = new CopyOnWriteArrayList<>();
            personIds.forEach(p -> {
                LfZdryApproveLogEntity log = new LfZdryApproveLogEntity();
                BeanUtils.copyProperties(logEntity, log);
                log.setSpId(p);
                log.setId(String.valueOf(KeyWorker.nextId()));
                logEntityList.add(log);
            });
            //保存日志
            if (!logEntityList.isEmpty())
                approveLogService.saveBatch(logEntityList);
        }
    }

    @Override
    @Transactional
    public void approveKMSpecialPerson(LfZdryApproveLogEntity logEntity) {
        if (StringUtils.isEmpty(logEntity.getSpId()))
            throw new BusinessException(500, "重点人员ID不能为空");
        if (StringUtils.isEmpty(logEntity.getOperateDept()) || StringUtils.isEmpty(logEntity.getCreator()))
            throw new BusinessException(500, "操作人或部门不能为空");
//        if (StringUtils.isEmpty(logEntity.getApproveStatus()))
//            throw new BusinessException(500, "操作状态不能为空");
        else {
//            int aStatus = Integer.parseInt(logEntity.getApproveStatus());
//            if(aStatus<ArmingTaskEnum.WAIT_POLICE_TYPE.ordinal() || aStatus>ArmingTaskEnum.FINISH_TYPE.ordinal())
//                throw new BusinessException(500,"非法操作状态");
            //查询重点人员信息
            logEntity.setId(String.valueOf(KeyWorker.nextId()));
            try {
				//保存日志
				if (logEntity != null)
				    approveLogService.saveLogEntity(logEntity);
			} catch (Exception e) {
//				log.error(logEntity.getId()+"|"+logEntity.getSpId()+"|"+logEntity.getAddition()+"|"+logEntity.getOperateDept()+"|"+e.getMessage());
				e.printStackTrace();
			}
        }
    }


    @Override
    @Transactional
    public Object uploadSp(FilePart filePart,ServerWebExchange exchange) throws Exception {
        //组织身份证号在库中存在的数据
        List<LfZdryExportDataEntity> listSfzh = new ArrayList<>();
        FileInputStream inputStream = null;
        Workbook wb = null;
        try {
            AccountBo bo = requestUtils.getCurrentUser(exchange);
            if (bo == null) {
                throw new BusinessException(10019,"此账号已在别处登录，请查证");
            }
            Path path = Files.createTempFile("excel", filePart.filename());
            filePart.transferTo(path.toFile());
            inputStream = new FileInputStream(new File(path.toString()));
            if (filePart.filename().endsWith("xls") || filePart.filename().endsWith("xlsx")) {
                wb = new XSSFWorkbook(inputStream);
            } else
                throw new BusinessException(500, "非法文件格式");
            Sheet sheet = wb.getSheetAt(0);


            if (sheet == null)
                throw new BusinessException(500, "请检查Excel文件是否存在内容");
            int rowSize = sheet.getLastRowNum() + 1;
            log.info("import file contains " + rowSize + " record");

            //1 先进行校验  只要有一行不通过就不进行添加
            //2 校验通过后在进行添加
            String version = UUIDUtils.getUUID();
            List<String> checkFailMsg = new ArrayList<>();               // 校验的错误信息
            //List<List<Object>> originalData = new ArrayList<>();  // execl原始数据
            List<LfZdryExportDataEntity> data = new ArrayList<>();                // 真是需要添加或者更新的数据

            // 检验实现多线程
            ExecutorService checkPool = Executors.newFixedThreadPool(10);
            try {
                CountDownLatch checkLatch = new CountDownLatch(10);
                BigDecimal b = new BigDecimal(rowSize);
                BigDecimal threadNumber = new BigDecimal(10);
                Integer threadCount = (int)Math.ceil(b.divide(threadNumber).doubleValue());

                List< Future<List<Map<String, Object>>>> checkFutureList = new ArrayList<>();
                Date startTime = new Date();
                //校验参数
                Map<String,List<String>> checkParam = new HashMap<>();

                List<String> zrgkfj = sysDictService.getByType("kp_zrgkfj").stream().map(SysDictEntity::getValue).collect(Collectors.toList());
                // List<String> zrgkfj =cacheableService.getAllGkzrfj("2");  //管控责任分局
                checkParam.put("zrgkfj",zrgkfj);
                List<String> zrpcs =cacheableService.getAllGkzrfj("3");  //管控派出所
                checkParam.put("zrpcs",zrpcs);
                List<String> provinces = cacheableService.getRegionByLevel(1);   //所有省
                checkParam.put("provinces",provinces);
                List<String> cities = cacheableService.getRegionByLevel(2);      //所有市
                checkParam.put("cities",cities);
                List<String> countries = cacheableService.getRegionByLevel(3);   //所有县
                checkParam.put("countries",countries);
                List<String> dles = kmZdryZrbmService.getAllZrbm()
                        .stream().map(KmZdryZrbmEntity::getRydl).collect(Collectors.toList()); // 获取所有大类
                checkParam.put("dles",dles);
                List<String> xles = kmZdryZrbmService.getAllZrbm()
                        .stream().map(KmZdryZrbmEntity::getRyxl).collect(Collectors.toList()); // 获取所有小类
                checkParam.put("xles",xles);
                List<String> rysxes =  JSONArray.parseArray(iSysDictService.getByTypeRedis("zdry_ryxx"),SysDictEntity.class)
                        .stream().map(SysDictEntity::getValue).collect(Collectors.toList()); // 获取所有人员属性
                checkParam.put("rysxes",rysxes);
                List<String> gkjbes = JSONArray.parseArray(iSysDictService.getByTypeRedis("kp_gkjb"),SysDictEntity.class)
                        .stream().map(SysDictEntity::getValue).collect(Collectors.toList()); // 获取所有管控级别
                checkParam.put("gkjbes",gkjbes);
               /* List<String> yjczlbes = JSONArray.parseArray(iSysDictService.getByTypeRedis("zdry_yjczlb"),SysDictEntity.class)
                        .stream().map(SysDictEntity::getValue).collect(Collectors.toList()); // 获取所有管控级别*/
                List<String> yjczlbes = Arrays.asList("核查","关注","控制","抓捕");
                checkParam.put("yjczlbes",yjczlbes);

                List<String> sszs = JSONArray.parseArray(iSysDictService.getByTypeRedis("yn_zs"),SysDictEntity.class)
                        .stream().map(SysDictEntity::getValue).collect(Collectors.toList());  // 获取所有州市
                checkParam.put("sszs",sszs);

                for(int i=0;i<10;i++) {
                    int start = i * threadCount;
                    int end = 0;
                    if ((start + threadCount) < rowSize) end = start + threadCount;
                    else end = rowSize;
                    int endNumber = end;
                    Future<List<Map<String, Object>>> future = checkPool.submit(new CheckExeclHandle(start,endNumber,sheet,checkLatch,this,checkParam));
                    checkFutureList.add(future);
                }
                checkLatch.await(); // 主线程停留在此处，等待执行完毕
                //组织身份证号在库中存在的数据
//                List<LfZdryBaseEntity> listSfzh = new ArrayList<>();
                Boolean flag = true;
                for(int i=0;i<checkFutureList.size();i++){
                    try {
                        List<Map<String, Object>> threadData = checkFutureList.get(i).get();
                        for(Map<String, Object> map : threadData){
                            if(map.containsKey("checkMag") && map.get("checkMag")!=null){
                                List<String> chFmsg = ( List<String>)map.get("checkMag");
                                if(chFmsg.size()>0){
                                  checkFailMsg.addAll(chFmsg);   //添加校验信息
                                  //continue;
                                }
                             }
                            if(map.containsKey("data") && map.get("data")!=null){
                                LfZdryExportDataEntity zdry = (LfZdryExportDataEntity)map.get("data");
                                    //校验execl中有没有身份证相同的记录
                                List<Integer> repeatRow = new ArrayList<>();
                                if(null != zdry && null != zdry.getSfzh()){
                                    for(LfZdryExportDataEntity z : data){  // 校验execl数据重复
                                        if(zdry.getSfzh().equals(z.getSfzh())){
                                            if(!zdry.getXm().equals(z.getXm())){
                                                repeatRow.add(z.getRowIndex());
                                            }
                                        }
                                    }
                                    if(repeatRow.size()>0){
                                        StringBuilder sb = new StringBuilder();
                                        sb.append("第").append(zdry.getRowIndex()).append("行数据和第 ").append(StrUtils.collectionToString(repeatRow,","))
                                                .append("行").append("的身份证相同,姓名不同，请修正数据。<br>");
                                        checkFailMsg.add(sb.toString());
                                    }
                                    // 校验这个数据是否在系统中已经存在
                                    LfZdryBaseEntity lz = lfZdryBaseService.getOne(new QueryWrapper<LfZdryBaseEntity>().lambda().eq(LfZdryBaseEntity::getSfzh,zdry.getSfzh()));
//                                    if(null!=lz && !lz.getXm().equals(zdry.getXm())){
//                                        StringBuilder sb = new StringBuilder();
//                                        sb.append("第 ").append(zdry.getRowIndex()).append("行重点人员的身份证号【").append(zdry.getSfzh())
//                                                .append("】已经在系统中存在，但是姓名不同，请修正数据或者在系统中编辑此重点人员。<br>");
//                                        checkFailMsg.add(sb.toString());
//                                        //continue;
//                                    }
                                    if(null != lz){
                                        listSfzh.add(zdry);
                                        flag = false;
                                    }else {
                                        flag = true;
                                    }
                                }
                                if(flag){
                                    zdry.setVersion(version);
                                    zdry.setHanSign(0);
                                    data.add(zdry);
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("检验时发生异常：==========》{}",e.getMessage());
                        return "校验时发生错误，导入失败";
                    }
                }
                log.info("校验花费的时间为："+((new Date().getTime()-startTime.getTime())/1000)+"秒");
            } finally {
                checkPool.shutdown();
            }
            List<Object> objectList = new ArrayList<>();
            objectList.add("execl导入时校验不通过信息：<br>");
            //如果有校验不通过的数据直接返回execl
            if (checkFailMsg.size() > 0) {
//                StringBuilder sb = new StringBuilder("execl导入时校验不通过信息：<br>");
                for (String msg :  checkFailMsg) {
//                    sb.append(msg);
                    objectList.add(msg);
                }
                //throw new BusinessException(201,sb.toString());
//                return sb.toString();
                return objectList;
            }
            log.info("execl数据校验完成，进行批量入库");

            //判断是否有需要插入的数据
            if(data.size() == 0){
                return listSfzh;
            }
            // 将校验完的数据插入到原始数据表
            List<List<LfZdryExportDataEntity>> saveData = ListUtils.splitList(data,2000);
            ExecutorService pool = Executors.newFixedThreadPool(saveData.size());
            try {
                CountDownLatch latch = new CountDownLatch(saveData.size());
                List<Future> futures = new CopyOnWriteArrayList<>();
                for( int i=0;i<saveData.size();i++){
                    List<LfZdryExportDataEntity> tempData = saveData.get(i);
                    Future<Boolean> future  =  pool.submit(new SaveExeclHandle(latch,tempData,lfZdryExportDataService));
                    futures.add(future);
                }
                latch.await();

                for(Future<Boolean> f : futures){
                    try {
                        boolean result = f.get();
                        if(!result) {
                            lfZdryExportDataService.deleteByVersion(version);
                            return "插入原始数据失败！";
                        }
                    } catch (Exception e) {
                        log.error("导入时发生异常，根据版本号删除");
                        lfZdryExportDataService.deleteByVersion(version);
                        return "插入原始数据失败！";
                    }
                }
            } finally {
                pool.shutdown();
            }
            List<LfZdryExportDataEntity> zdryExportDataTemp = lfZdryExportDataService
                    .list(new QueryWrapper<LfZdryExportDataEntity>().lambda().eq(LfZdryExportDataEntity::getHanSign,0)
                            .isNotNull(LfZdryExportDataEntity::getXm).isNotNull(LfZdryExportDataEntity::getSfzh));
            CopyOnWriteArrayList<LfZdryExportDataEntity> zdryExportData = new CopyOnWriteArrayList<>();
            zdryExportData.addAll(zdryExportDataTemp);
            Iterator<LfZdryExportDataEntity> it = zdryExportData.iterator();
            Lock lock = new ReentrantLock();
            while (it.hasNext()){
                final LfZdryExportDataEntity zdry = it.next();
                executorService.execute(new SaveLfZdryBaseHandle(this,lfZdryBaseService,kmZdryTypeService,
                        kmZdryAssistService,kmZdryHomeService,lfZdryExportDataService,tKmProRightService,lfZdryHistoryLogService,specialPersonComponent,zdry,bo,exchange,lock));
             }
            LfZdryBaseEntity lfZdry = new LfZdryBaseEntity();
            this.operatLog("新增", bo, lfZdry, "导入重点人员","数据导入",exchange);
//           return "原始数据已经校验完，并插入数据库中。";
            return listSfzh;
        }catch (Exception e){
            log.error("error==>{}", e.getMessage());
            throw new BusinessException(500, "导入execl发生错误！");
        } finally {
        	
            try {
                if (wb != null)
                    wb.close();
                if (inputStream != null)
                    inputStream.close();
            } catch (IOException e) {
                log.error("error==>{}", e.getMessage());
                throw new BusinessException(500, "导入execl发生错误！");
            }
        }

    }
    
	public void operatLog(String type,AccountBo bo,LfZdryBaseEntity entity,String logRecord,String opinion,ServerWebExchange exchange) {
   		//历史记录
   		LfZdryHistoryLogEntity history = new LfZdryHistoryLogEntity();
        history.setCreator(bo.getPersonBo().getName());
        history.setCreatorCode(bo.getPersonBo().getPoliceCode());
        history.setCreateTime(new Date());
   		history.setSpId(entity.getId());
   		history.setApproveResult(logRecord);
   		history.setOperation(type);
   		history.setOperateDept(bo.getOrganizationBo().getShortName());
   		history.setAddition(opinion);
   		history.setFunctionModule("重点人员模块");

		ServerHttpRequest request = exchange.getRequest();
		String ip = getRemoteIpUtil.getRemoteIP(request);
		history.setOperateIp(ip);
		history.setType(3);
   		lfZdryHistoryLogService.save(history);
   		
	}



    /**
     * 校验和解析execl中的每一行数据
     *
     * @param sheet
     * @param rowIndex
     * @return
     * @throws ParseException
     */
        public Map<String,Object> checkData(Sheet sheet, Integer rowIndex,Map<String,List<String>> checkParam) throws ParseException {
        Map<String,Object> resultMap = new HashMap<>();
        Row row = sheet.getRow(rowIndex);
        //log.info("检验到第：【"+rowIndex+"】行，row 为："+row);
        //List<Object> originalData = new ArrayList<>();
        List<String> checkErrorMsg = new ArrayList<>();
        LfZdryExportDataEntity data = new LfZdryExportDataEntity();

        // String gkfjtemp = null;  派出所名称前不带分局
        StringBuilder sb = new StringBuilder();
        StringBuilder passNumberBuild = new StringBuilder();
        for (int j = 0; j < 33; j++) {
            Cell cell = row.getCell(j);
            switch (j) {
                case 0: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        data.setXh(transCellVal(cell).trim());
                    }
                }
                break;
                case 1: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        boolean res = CheckUtil.checkSpecialCharactersAndBlank(transCellVal(cell).trim());
                        if (res) {
                            //int[] array = {rowIndex, 1};
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第2列【姓名】校验不通过;<br>");
                            continue;
                        }
                        data.setXm(transCellVal(cell).trim());
                    }
                }
                break;
                case 2: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        boolean res = CheckUtil.IDCardValidate(transCellVal(cell).trim());
                        if (!res) {
                            //int[] array = {rowIndex, 2};
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第3列【身份证号】校验不通过;<br>");
                            continue;
                        }
                        data.setSfzh(transCellVal(cell).trim());
                    }
                }
                break;
                case 3: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String phoneNum1 = transformPhoneNumber(cell);
                        if (phoneNum1.length() > 0) {
                            boolean res = CheckUtil.checkPhoneNumber(phoneNum1.trim());
                            if (!res) {
                                //int[] array = {rowIndex, 3};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第4列【手机号】校验不通过;<br>");
                                continue;
                            }
                        }
                        sb.append(phoneNum1);
                        data.setSjh(sb.toString());
                    }
                }
                break;
                case 4: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String phoneNum2 = transformPhoneNumber(cell);
                        if (phoneNum2.length() > 0) {
                            boolean res = CheckUtil.checkPhoneNumber(phoneNum2.trim());
                            if (!res) {
                                //int[] array = {rowIndex, 4};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第5列【手机号】校验不通过;<br>");
                                continue;
                            }
                        }else continue;
                        if (sb.length() > 0)
                            sb.append(",").append(phoneNum2);
                        else sb.append(phoneNum2);
                        data.setSjh(sb.toString());
                    }
                }
                break;
                case 5: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String phoneNum3 = transformPhoneNumber(cell);
                        if (phoneNum3.length() > 0) {
                            boolean res = CheckUtil.checkPhoneNumber(phoneNum3.trim());
                            if (!res) {
                                //int[] array = {rowIndex, 5};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第6列【手机号】校验不通过;<br>");
                                continue;
                            }
                        }else continue;
                        if (sb.length() > 0)
                            sb.append(",").append(phoneNum3);
                        else sb.append(phoneNum3);
                        data.setSjh(sb.toString());
                    }
                }
                break;
                case 6: {
                    //originalData.add(transCellVal(cell));
                    if(rowIndex > 0){
                        String wx = transformWx(cell);
                        if (transCellVal(cell).length() > 0) {
                           /* 20200708 取消微信校验
                            boolean res = CheckUtil.checkWx(wx);
                            if (!res) {
                                //int[] array = {rowIndex, 6};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第7列【微信】校验不通过;<br>");
                                continue;
                            }*/
                            data.setWx(wx);
                        }
                    }
                }
                break;
                case 7: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String qq = transformWx(cell).trim();
                        if (qq.length() > 0) {
                            boolean res = CheckUtil.checkQq(qq);
                            if (!res) {
                                //int[] array = {rowIndex, 7};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第8列【qq号码】校验不通过;<br>");
                                continue;
                            }
                            data.setQq(qq);
                        }
                    }
                }
                break;
                case 8: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() > 0) {
                            boolean res = CheckUtil.isCarnumberNO(transCellVal(cell).trim());
                            if (!res) {
                                //int[] array = {rowIndex, 8};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第9列【名下车辆号牌】校验不通过;<br>");
                                continue;
                            }
                            data.setMxcph(transCellVal(cell));
                        }
                    }
                }
                break;
                case 9: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() > 0) {
                            boolean res = CheckUtil.isCarnumberNO(transCellVal(cell).trim());
                            if (!res) {
                                //int[] array = {rowIndex, 9};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第10列【实际使用车辆号牌】校验不通过;<br>");
                                continue;
                            }
                            data.setSjsyclhp(transCellVal(cell));
                        }
                    }
                }
                break;
                case 10: { //州市
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String sszsmc = transCellVal(cell).trim();
                        if(sszsmc.length()<=0){
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第11列【州市】为空;<br>");
                            continue;
                        }else{
                          boolean result =   checkParam.get("sszs").contains(sszsmc);
                          if(result){
                              data.setSszsmc(sszsmc);
                          }else{
                              checkErrorMsg.add("第"+(rowIndex+1)+"行，第11列【州市】校验不通过;<br>");
                              continue;
                          }
                        }
                    }
                }break;
                case 11: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String ssxq = transCellVal(cell).trim();
                        if(ssxq.length()<=0) {
                            checkErrorMsg.add("第" + (rowIndex + 1) + "行，第12列【管控责任分局】为空;<br>");
                            continue;
                        }
                        if(null !=data.getSszsmc() && data.getSszsmc().equals("昆明")) {
                            boolean result = checkParam.get("zrgkfj").contains(ssxq);
                            if (!result) {
                                //int[] array = {rowIndex, 10};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第" + (rowIndex + 1) + "行，第12列【管控责任分局】校验不通过;<br>");
                                continue;
                            }
                        }
                        //gkfjtemp = transCellVal(cell);
                        data.setSsxq(transCellVal(cell).trim());
                    }
                }
                break;
                case 12: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String pcs = transCellVal(cell).trim();
                        if(pcs.length()>0){
                            if(null != data.getSszsmc() && data.getSszsmc().equals("昆明")){
                                boolean result = checkParam.get("zrpcs").contains(pcs);
                                if (!result) {
                                    //int[] array = {rowIndex, 11};
                                    //checkErrorMsg.add(array);
                                    checkErrorMsg.add("第"+(rowIndex+1)+"行，第13列【责任派出所】校验不通过;<br>");
                                    continue;
                                }
                            }
                            data.setSspcs(pcs);
                        }
                    }
                }
                break;
                case 13: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String gkmj = transCellVal(cell).trim();
                        if(gkmj.length()>0){
                            if(null != data.getSszsmc() && data.getSszsmc().equals("昆明")){
                                boolean res = CheckUtil.checkSpecialCharactersAndBlank(gkmj);
                                if (res) {
                                    //int[] array = {rowIndex, 12};
                                    //checkErrorMsg.add(array);
                                    checkErrorMsg.add("第"+(rowIndex+1)+"行，第14列【责任民警】校验不通过;<br>");
                                    continue;
                                }
                            }
                            data.setGkmj(gkmj);
                        }
                    }
                }
                break;
                case 14: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        String phoneNum = transformPhoneNumber(cell).trim();
                        if (phoneNum.length() > 0) {
                            if(null != data.getSszsmc() && data.getSszsmc().equals("昆明")){
                                boolean res = CheckUtil.checkPhoneNumber(phoneNum);
                                if (!res) {
                                    //int[] array = {rowIndex, 13};
                                    //checkErrorMsg.add(array);
                                    checkErrorMsg.add("第"+(rowIndex+1)+"行，第15列【责任民警电话】校验不通过;<br>");
                                    continue;
                                }
                            }
                            data.setMjlxdh(phoneNum);
                        }
                    }
                }
                break;
                case 15: {
                   // originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        boolean result = checkParam.get("provinces").contains(transCellVal(cell).trim());
                        if (!result) {
                            //int[] array = {rowIndex, 14};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第16列【户籍省】校验不通过;<br>");
                            continue;
                        }
                        data.setHjs(transCellVal(cell).trim());
                    }
                }
                break;
                case 16: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        boolean result = checkParam.get("cities").contains(transCellVal(cell).trim());
                        if (!result) {
                            //int[] array = {rowIndex, 15};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第17列【户籍市】校验不通过;<br>");
                            continue;
                        }

                        data.setHjss(transCellVal(cell).trim());
                    }

                }
                break;
                case 17: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        boolean result = checkParam.get("countries").contains(transCellVal(cell).trim());
                        if (!result) {
                            //int[] array = {rowIndex, 16};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第18列【户籍县】校验不通过;<br>");
                        }

                        data.setHjx(transCellVal(cell).trim());
                    }
                }
                break;
                case 18: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (rowIndex > 0) {
                            boolean res = CheckUtil.checkSpecialCharactersAndBlank(transCellVal(cell).trim());
                            if (res) {
                                //int[] array = {rowIndex, 17};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第19列【户籍地】校验不通过;<br>");
                                continue;
                            }

                            data.setHjd(transCellVal(cell).trim());
                        }
                    }
                }
                break;
                case 19: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() > 0) {
                            boolean result = checkParam.get("provinces").contains(transCellVal(cell).trim());
                            if (!result) {
                               // int[] array = {rowIndex, 18};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第20列【实际居住省】校验不通过;<br>");
                                continue;
                            }
                            data.setXzzs(transCellVal(cell));
                        }
                    }
                }
                break;
                case 20: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() > 0) {
                            boolean result = checkParam.get("cities").contains(transCellVal(cell).trim());
                            if (!result) {
                                //int[] array = {rowIndex, 19};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第21列【实际居住市】校验不通过;<br>");
                                continue;
                            }
                            data.setXzzss(transCellVal(cell));
                        }
                    }
                }
                break;
                case 21: {
                   // originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() > 0) {
                            boolean result = checkParam.get("countries").contains(transCellVal(cell).trim());
                            if (!result) {
                                //int[] array = {rowIndex, 20};
                                //checkErrorMsg.add(array);
                                checkErrorMsg.add("第"+(rowIndex+1)+"行，第22列【实际居住地县】校验不通过;<br>");
                                continue;
                            }
                            data.setXzzx(transCellVal(cell));
                        }
                    }
                }
                break;
                case 22: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (rowIndex > 0) {
                            if (transCellVal(cell).length() > 0) {
                                boolean res = CheckUtil.checkSpecialCharactersAndBlank(transCellVal(cell).trim());
                                if (res) {
                                    //int[] array = {rowIndex, 21};
                                    //checkErrorMsg.add(array);
                                    checkErrorMsg.add("第"+(rowIndex+1)+"行，第23列【实际居住地】校验不通过;<br>");
                                    continue;
                                }
                                data.setXzz(transCellVal(cell));
                            }
                        }
                    }
                }
                break;
                case 23: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() <= 0) {
                            //int[] array = {rowIndex, 22};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第24列【人员大类】校验不通过(人员大类不能为空);<br>");
                            continue;
                        }
                        boolean result = checkParam.get("dles").contains(transCellVal(cell).trim());
                        if (!result) {
                            //int[] array = {rowIndex, 22};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第23列【人员大类】校验不通过(人员大类不正确);<br>");
                            continue;
                        }

                        data.setRylbx(transCellVal(cell).trim());
                    }
                }
                break;
                case 24: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() <= 0) {
                            //int[] array = {rowIndex, 23};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第25列【人员小类】校验不通过(人员小类不能为空);<br>");
                            continue;
                        }
                        boolean result = checkParam.get("xles").contains(transCellVal(cell).trim());
                        if (!result) {
                            //int[] array = {rowIndex, 23};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第24列【人员小类】校验不通过(人员小类不正确);<br>");
                            continue;
                        }
                        data.setXl(transCellVal(cell).trim());
                    }
                }
                break;
                case 25: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() <= 0) {
                            //int[] array = {rowIndex, 24};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第26列【人员小类】校验不通过(人员属性不能为空);<br>");
                            continue;
                        }
                        boolean result = checkParam.get("rysxes").contains(transCellVal(cell).trim());
                        if (!result) {
                            //int[] array = {rowIndex, 24};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第26列【人员小类】校验不通过(人员属性不正确);<br>");
                            continue;
                        }

                        data.setRysx(transCellVal(cell).trim());
                    }
                }
                break;
                case 26: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() <= 0) {
                            //int[] array = {rowIndex, 25};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第27列【风险等级】校验不通过(风险等级不能为空);<br>");
                            continue;
                        }
                        boolean result = checkParam.get("gkjbes").contains(transCellVal(cell).trim());
                        if (!result) {
                            //int[] array = {rowIndex, 25};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第27列【风险等级】校验不通过(风险等级不正确);<br>");
                            continue;
                        }
                        data.setGkjbx(transCellVal(cell));
                    }
                }
                break;
                case 27: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        if (transCellVal(cell).length() <= 0) {
                            //int[] array = {rowIndex, 26};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第28列【预警处置类别】校验不通过(预警处置类别不正确);<br>");
                            continue;
                        }
                        boolean result = checkParam.get("yjczlbes").contains(transCellVal(cell).trim());
                        if (!result) {
                            //int[] array = {rowIndex, 26};
                            //checkErrorMsg.add(array);
                            checkErrorMsg.add("第"+(rowIndex+1)+"行，第28列【预警处置类别】校验不通过(预警处置类别不正确);<br>");
                            continue;
                        }
                        data.setYjczlb(transCellVal(cell));
                    }
                }
                break;
                case 28: {
                    //originalData.add(transCellVal(cell));
                    if (rowIndex > 0) {
                        data.setBz(transCellVal(cell));
                    }
                }
                break;
                case 29:{ //诉求
                    if(rowIndex>0){
                        String appeal = transCellVal(cell);
                        if(appeal.length()>0){
                            data.setAppeal(appeal);
                        }
                    }
                }break;
                //出入证证件号
                case 30: {
                    if (rowIndex > 0) {
                        String passNumber1 = transCellVal(cell);
                        if (passNumber1.length() > 0) {
                            passNumberBuild.append(passNumber1);
                            data.setPassNumber(passNumberBuild.toString());
                        }
                    }
                }
                break;
                case 31: {
                    if (rowIndex > 0) {
                        String passNumber2 = transCellVal(cell);
                        if (passNumber2.length() > 0) {
                            if (passNumberBuild.length() > 0)
                                passNumberBuild.append(",").append(passNumber2);
                            else passNumberBuild.append(passNumber2);
                            data.setPassNumber(passNumberBuild.toString());
                        }
                    }
                }
                break;
                case 32: {
                    if (rowIndex > 0) {
                        String passNumber3 = transCellVal(cell);
                        if (passNumber3.length() > 0) {
                            if (passNumberBuild.length() > 0)
                                passNumberBuild.append(",").append(passNumber3);
                            else passNumberBuild.append(passNumber3);
                            data.setPassNumber(passNumberBuild.toString());
                        }
                    }
                }
                break;
            }

        }
        if(rowIndex > 0){
            resultMap.put("checkMag",checkErrorMsg);
            data.setRowIndex(rowIndex+1);
            resultMap.put("data",data);
        }
        return resultMap;
    }

    /**
     * 整理数据
     *
     * @param kmzd
     * @return
     */
    private KmZdryDto arrangeData(KmZdryDto kmzd) {
        try {
            kmzd.setXb(checkSex(kmzd.getSfzh()));  //设置性别
            //设置ID
            kmzd.setId(String.valueOf(KeyWorker.nextId()));
            Map<String, String> hjdxy = searchLngLat(kmzd.getHjs(), kmzd.getHjsS(), kmzd.getHjx(), kmzd.getHjd());  //户籍地经纬度
            if (null != hjdxy) {
                kmzd.setHjdX(hjdxy.get("x"));
                kmzd.setHjdY(hjdxy.get("y"));
            }
            Map<String, String> sjxy = searchLngLat(kmzd.getXzzs(), kmzd.getXzzsS(), kmzd.getXzzx(), kmzd.getXzz()); //现居住地经纬度
            if (null != sjxy) {
                kmzd.setX(sjxy.get("x"));
                kmzd.setY(sjxy.get("y"));
            }
            SysDictEntity sysDictEntity = iSysDictService.getDictByTypeAndVal("kp_gkjb", kmzd.getGkjbx());
            if (null != sysDictEntity) {
                kmzd.setGkjb(sysDictEntity.getKey());
            }
            SysDictEntity dictEntity = sysDictService.getDictByTypeAndVal("kp_ssxq", kmzd.getSsxq());
            if (null != dictEntity) {
                kmzd.setSsxqId(dictEntity.getKey());
            }

            /*// 查询管控分局id
            Map<String,Object> map = cacheableService.getOrganization(kmzd.getSsxq());
            if(null != map)
            kmzd.setSsxqId(map.get("id").toString());
            // 查询所属派出所id
            Map<String,Object> pcs = cacheableService.getOrganization(kmzd.getSspcs());
            if(null != pcs)

            kmzd.setSsxqId(pcs.get("id").toString());*/
            // 根据管控民警查询民警id
            Map<String,Object> mj = cacheableService.getZrmjInfo(kmzd.getGkmj());
            if(null != mj)
            kmzd.setMjid(mj.get("id").toString());

            kmzd.setApproveStatus("4");
            kmzd.setProcessType(0);
            //kmzd.setWkzt("已稳控");
            SysDictEntity rysxdictEntity = sysDictService.getDictByTypeAndVal("zdry_ryxx", kmzd.getRysxName());
            if (null != rysxdictEntity) {
                kmzd.setRysx(Integer.parseInt(rysxdictEntity.getKey()));
            }
            if(kmzd.getYjczlbName()!=null && kmzd.getYjczlbName().length()>0){
                if(kmzd.getYjczlbName().equals("控制") || kmzd.getYjczlbName().equals("抓捕")){
                    kmzd.setYjczlbName("控制（抓捕）");
                }
            }
            SysDictEntity yjczlbdictEntity = sysDictService.getDictByTypeAndVal("zdry_yjczlb", kmzd.getYjczlbName());
            if (null != yjczlbdictEntity) {
                    kmzd.setYjczlb(Integer.parseInt(yjczlbdictEntity.getKey()));
            }
            return kmzd;
        } catch (Exception e) {
            log.error(e.getMessage(), "导入数据库时，封装数据出错。");
        }
        return null;
    }

    public void arrangeZdryBaseData(LfZdryBaseEntity zdry,LfZdryExportDataEntity orZdry){
        //zdry.setId(String.valueOf(KeyWorker.nextId()));
        zdry.setXb(checkSex(zdry.getSfzh()));

        // 查询主责警种 新增时为主责
        if(null != orZdry){
            KmZdryZrbmEntity zrbm = kmZdryZrbmService.queryZrbmByDlAndXl(orZdry.getRylbx(),orZdry.getXl());
            if(null != zrbm) zdry.setZrbm(zrbm.getZrbm());
        }

        Map<String, String> hjdxy = searchLngLat(zdry.getHjs(), zdry.getHjss(), zdry.getHjx(), zdry.getHjd());  //户籍地经纬度
        if (null != hjdxy) {
            zdry.setHjdX(hjdxy.get("x"));
            zdry.setHjdY(hjdxy.get("y"));
        }


        Map<String, String> sjxy = searchLngLat(zdry.getXzzs(), zdry.getXzzss(), zdry.getXzzx(), zdry.getXzz()); //现居住地经纬度
        if (null != sjxy) {
            zdry.setX(sjxy.get("x"));
            zdry.setY(sjxy.get("y"));
        }
        SysDictEntity sysDictEntity = iSysDictService.getDictByTypeAndVal("kp_gkjb", zdry.getGkjb());
        if (null != sysDictEntity) {
            zdry.setGkjbCode(sysDictEntity.getKey());
        }
        if(null != zdry.getSsxq() && zdry.getSsxq().length()>0) {// 查询管控分局id
            Map<String, Object> map = cacheableService.getOrganization(zdry.getSsxq(), null);
            if (null != map)
                zdry.setSsxqId(map.get("id").toString());
        }

        if(null !=zdry.getSspcs() && zdry.getSspcs().length()>0){// 查询所属派出所id
            Map<String,Object> pcs = cacheableService.getOrganization(zdry.getSspcs(),zdry.getSsxqId());
            if(null != pcs)
                zdry.setSspcsId(pcs.get("id").toString());
        }
        // 根据管控民警查询民警id
        Map<String,Object> mj = cacheableService.getZrmjInfo(zdry.getGkmj());
        if(null != mj)
            zdry.setMjid(mj.get("id").toString());

        zdry.setApproveStatus("4");
        zdry.setProcessType(0);
        SysDictEntity rysxdictEntity = sysDictService.getDictByTypeAndVal("zdry_ryxx", zdry.getRysxName());
        if (null != rysxdictEntity) {
            zdry.setRysx(Integer.parseInt(rysxdictEntity.getKey()));
        }

        SysDictEntity yjczlbdictEntity = sysDictService.getDictByTypeAndVal("zdry_yjczlb", zdry.getYjczlbName());
        if (null != yjczlbdictEntity) {
            if (yjczlbdictEntity.getKey().equals("11505")) zdry.setYjczlb(Integer.parseInt("11506"));
            else
                zdry.setYjczlb(Integer.parseInt(yjczlbdictEntity.getKey()));
        }
    }

    public void arrangeZdryTypeData(KmZdryTypeEntity zt){
        // 根据人员大类 和 小类查询 警种
        KmZdryZrbmEntity zrbm = kmZdryZrbmService.queryZrbmByDlAndXl(zt.getRylb(),zt.getXl());
        if(null != zrbm) zt.setZrbm(zrbm.getZrbm());
        // 查询大类信息
        KmZdryZrbmEntity rydl = kmZdryZrbmService.queryDlInfo(zt.getRylb());
        if(null != rydl) zt.setRylbCode(rydl.getRydlCode());
        // 查询小类信息
        KmZdryZrbmEntity ryxl = kmZdryZrbmService.queryXlInfo(zt.getXl());
        if(null != ryxl) zt.setXlCode(ryxl.getRyxlCode());
    }

    /**
     * 四级截断式查询经纬度
     *
     * @param province 省
     * @param city     市
     * @param country  县
     * @param village  镇
     * @return
     */
    @Override
    public Map<String, String> searchLngLat(String province, String city, String country, String village) {
        try {
            List<String> paramsList = Arrays.asList(province, city, country, village);
            Map<String, String> resultMap = new HashMap<>();
            StringBuilder sb = new StringBuilder();
            int flag = 3;
            while (flag >= 0) {
                for (int i = 0; i <= flag; i++) {
                    if (null != paramsList.get(i) && paramsList.get(i).length() > 0) sb.append(paramsList.get(i));
                }
                resultMap = checkXY(sb.toString());
                if (null != resultMap) {
                    return resultMap;
                }
                flag--;
            }
        } catch (Exception e) {
            return null;
        }
        return null;
    }

    /**
     * 根据地址具体返回经纬度
     *
     * @return
     */
    public Map<String, String> checkXY(String address) throws Exception {
        StringBuilder sb = new StringBuilder(systemConfig.getAddressIp());
        sb.append("/api/poi/search").append("?address=").append(URLEncoder.encode(address, "UTF-8"))
                .append("&pageNo=1&pageSize=10");
        String data = HttpClientUtil.sendGetRequest(sb.toString(), "UTF-8");
        JSONObject json = (JSONObject) JSON.parseObject(data).get("data");
        JSONArray array = (JSONArray) json.get("poiList");
        if (array.size() > 0) {
            JSONObject obj = (JSONObject) array.get(0);
            String lng = String.valueOf(obj.get("gcjlon"));
            String lat = String.valueOf(obj.get("gcjlat"));
            Map<String, String> map = new HashMap<>();
            map.put("x", lng);
            map.put("y", lat);
            return map;
        }
        return null;
    }


    /**
     * 根据身份证解析姓名
     *
     * @param sfzh
     * @return
     */
    private String checkSex(String sfzh) {
        try {
            if (StringUtils.isEmpty(sfzh)) {
                return "未知";
            } else {
                Integer sexNum = null;
                if(sfzh.length()==18){
                    sexNum =Integer.valueOf(sfzh.substring(16, 17));
                } else if(sfzh.length() == 15){
                    sexNum = Integer.valueOf(sfzh.substring(14,15));
                }
                return (sexNum & 1) == 0 ? "女" : "男";
            }
        } catch (Exception e) {
            log.error("身份证获取性别异常："+e.getMessage());
            return "未知";
        }
    }

    private String transCellVal(Cell cell) {
        try {
            if (cell.getCellType() == CellType.NUMERIC)
                return String.valueOf(cell.getNumericCellValue());
            else
                return cell.getStringCellValue();
        } catch (Exception ignored) {
            return "";
        }
    }

    /**
     * 判断cell是否为空
     *
     * @param cell
     * @return
     */
    public boolean isCellEmpty(Cell cell) {
        if (cell == null || cell.getCellType() == CellType.BLANK) {
            return true;
        }

        if (cell.getCellType() == CellType.STRING && cell.getStringCellValue().isEmpty()) {
            return true;
        }

        return false;
    }

    /**
     * 转换电话号码，避免为科学计数法
     *
     * @param cell
     * @return
     */
    public String transformPhoneNumber(Cell cell) {
        try {
            if (isCellEmpty(cell)) {
                return "";
            }
            String phoneNum = null;
            DecimalFormat df = new DecimalFormat();
            if (cell.getCellType() == CellType.NUMERIC) {
                phoneNum = df.format(cell.getNumericCellValue()).replaceAll(",", "");
            } else {
                phoneNum = transCellVal(cell);
            }
            return phoneNum;
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 解析wx
     * @param cell
     * @return
     */
    public String transformWx(Cell cell){
        try {
            if (isCellEmpty(cell)) {
                return "";
            }
            String wx = null;
            DecimalFormat df = new DecimalFormat();
            if (cell.getCellType() == CellType.NUMERIC) {
                wx = df.format(cell.getNumericCellValue()).replaceAll(",", "");
            } else {
                wx = transCellVal(cell);
            }
            return wx;
        } catch (Exception e) {
            return "";
        }
    }

   /* *//**
     * 查询管控责任分局 和 责任派出所
     *
     * @param orgType
     * @return
     *//*
    public List<String> getAllGkzrfj(String orgType) {
        ResponseEntity result = restTemplate.getForEntity(systemConfig.getSystemServer() +
                "/api/system/organization/getOrgByOrgtype?orgType=" + orgType, JSONObject.class);
        List<String> returnResult = new ArrayList<>();
        if (null != result) {
            if (null != result.getBody()) {
                JSONObject obj = JSONObject.parseObject(result.getBody().toString());
                List<Map> res = JSONArray.parseArray(obj.get("data").toString(), Map.class);
                for (Map map : res) {
                    returnResult.add((String) map.get("shortName"));
                }

            }
        }
        return returnResult;
    }*/

   /* *//**
     * 查询区域 省：1；市：2；县：3；
     *
     * @param level
     * @return
     *//*
    public List<String> getRegionByLevel(Integer level) {
        ResponseEntity result = restTemplate.getForEntity(systemConfig.getSystemServer() +
                "/api/system/region/getRegionByType?level=" + level, JSONObject.class);
        if (null != result) {
            if (null != result.getBody()) {
                JSONObject obj = JSONObject.parseObject(result.getBody().toString());
                List<String> res = JSONArray.parseArray(obj.get("data").toString(), String.class);
                return res;
            }
        }
        return null;
    }*/
}
